/*
 * List.c
 *
 *  Created on: 11/11/2011
 *      Author: marcio
 */

#include "List.h"

typedef struct nl{
	void* elem;
	struct nl* next;
}NodeList;

List* list_newList(){
	List* l;
	l->head = malloc(sizeof(NodeList));
	l->last = l->head;
	return l;
}

int list_addFirst(List* l, void* elem){
	if(elem == NULL) return 1;
	if(l->head->next == NULL)return list_addLast(l,elem);
	NodeList* nd = malloc(sizeof(NodeList));
	nd->elem = elem;
	nd->next = ((NodeList*)l->head)->next;
	((NodeList*)l->head)->next = nd;
	return 0;
}

int list_addLast(List* l, void* elem){
	if(elem == NULL) return 1;
	NodeList* nd = malloc(sizeof(NodeList));
	nd->elem = elem;
	((NodeList*)l->last)->next = nd;
	((NodeList*)l->last) = nd;
	return 0;
}

void* list_getElemFirst(List* l){
	return l->head->next;
}

void* list_getElemLast(List* l){
	return l->last->next;
}

int list_removeElemFirst(List* l){
	if(l->head->next != NULL) l->head->next = l->head->next->next;
	return 0;
}

int list_removeElemLast(List* l){
	if(l->last->next != NULL) l->last->next = l->last->next->next;
	return 0;
}

int list_iterateModify(List* l, void* (*function)(void*)){
	NodeList* aux = l->head->next;
	while(aux != NULL){
		aux->elem = function(aux->elem);
		aux = aux->next;
	}
	return 0;
}

List* list_iterate(List* l, void* (*function)(void*)){
	List* l2 = list_newList();
	NodeList* aux = l->head->next;
	while(aux != NULL){
		list_addLast(l2,function(aux->elem));
		aux = aux->next;
	}
	return 0;
}

int list_order(List* l, int (*function)(void*, void*)){
	NodeList* aux ;
	NodeList* aux2;
	void* move;
	int change = 1;
	while(change != 0){
		aux = l->head->next;
		aux2 = l->head->next != NULL? l->head->next->next : NULL;
		change = 0;
		while(aux != NULL && aux2 != NULL){
			if(function(aux->elem, aux->elem) < 0){
				move = aux->elem;
				aux->elem = aux2->elem;
				aux2->elem = move;
				change = 1;
			}
			aux = aux2;
			aux2 = aux2->next;
		}
	}
	return 0;
}

int list_isEmpty(List* l){
	return l->head->next == NULL;
}
